﻿using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;

namespace EditorFramework
{
    /// <summary>
    /// 自定义搜索字段控件，继承自GUIBase，用于实现带模式切换的搜索功能
    /// </summary>
    public class SearchField : GUIBase
    {
        // 事件声明：当搜索模式改变时触发
        public event Action<int> OnModeChanged;
        // 事件声明：当搜索内容变化时触发
        public event Action<string> OnValueChanged;
        // 事件声明：当结束编辑时触发
        public event Action<string> OnEndEdit;

        // 当前选中的内容索引
        private int mContentIndex;
        // 当前搜索内容
        private string mSearchContent;
        // 可搜索内容数组
        private string[] mSearchableContents;
        // 用于调用私有API的反射方法信息
        private MethodInfo mDrawAPI;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="searchContent">初始搜索内容</param>
        /// <param name="searchableContents">可搜索内容数组</param>
        /// <param name="contentIndex">初始选中内容索引</param>
        public SearchField(string searchContent, string[] searchableContents, int contentIndex)
        {
            mContentIndex = contentIndex;
            mSearchContent = searchContent;
            mSearchableContents = searchableContents;

            // 通过反射获取EditorGUI的私有方法ToolbarSearchField
            mDrawAPI = typeof(EditorGUI).GetMethod("ToolbarSearchField",
                BindingFlags.NonPublic | BindingFlags.Static,
                null,
                new Type[] { typeof(int), typeof(Rect), typeof(string[]), typeof(int).MakeByRefType(), typeof(string) },
                null);
        }

        // 控件唯一标识ID
        private int mControlId;

        /// <summary>
        /// 重写OnGUI方法进行界面绘制
        /// </summary>
        /// <param name="position">控件绘制区域</param>
        public override void OnGUI(Rect position)
        {
            base.OnGUI(position);

            // 检查私有API是否可用
            if (mDrawAPI is not null)
            {
                // 获取唯一控件ID
                mControlId = GUIUtility.GetControlID("EditorSearchField".GetHashCode(), FocusType.Keyboard, position);

                // 准备调用参数
                int mode = mContentIndex;
                object[] args = new object[] { mControlId, position, mSearchableContents, mode, mSearchContent };

                // 调用私有方法绘制搜索栏
                string newSearchContent = mDrawAPI.Invoke(null, args) as string;

                // 处理模式变化事件
                if ((int)args[3] != mContentIndex)
                {
                    mContentIndex = (int)args[3];
                    OnModeChanged?.Invoke(mContentIndex);
                }

                // 处理内容变化事件
                if (mSearchContent != newSearchContent)
                {
                    mSearchContent = newSearchContent;
                    OnValueChanged?.Invoke(mSearchContent);
                }

                // 处理键盘输入事件
                Event e = Event.current;
                if (e.keyCode == KeyCode.Return || e.keyCode == KeyCode.Escape || e.character == '\n')
                {
                    if (GUIUtility.keyboardControl == mControlId)
                    {
                        // 结束键盘焦点
                        GUIUtility.keyboardControl = -1;
                        // 阻止默认输入行为
                        if (e.type != EventType.Repaint && e.type != EventType.Layout)
                        {
                            e.Use();
                        }
                        // 触发结束编辑事件
                        OnEndEdit?.Invoke(mSearchContent);
                    }
                }
            }
        }

        /// <summary>
        /// 重写资源释放方法
        /// </summary>
        protected override void OnDispose()
        {
            // 可在此添加资源释放逻辑
        }
    }
}